﻿/****************************************************************************************************
	Copyright (C) 2010 RapidWebDev Organization (http://rapidwebdev.org)
	Author: Eunge, Legal Name: Jian Liu, Email: eunge.liu@RapidWebDev.org

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using BaoJianSoft.Common;
using BaoJianSoft.Common.Data;
using BaoJianSoft.ExtensionModel.Statistic;
using BaoJianSoft.ExtensionModel.Web;
using BaoJianSoft.RapidWeb;
using BaoJianSoft.RapidWeb.DynamicPages;

namespace BaoJianSoft.ExtensionModel.Web.DynamicPage
{
	/// <summary>
	/// Dynamic page to manage statistic field.
	/// </summary>
	public abstract class StatisticFieldManagement : BaoJianSoft.RapidWeb.DynamicPages.DynamicPage
	{
		/// <summary>
		/// Query statistic fields of special statistic report which resolved by abstract method "GetStatisticDefinition".
		/// </summary>
		/// <param name="parameter"></param>
		/// <returns></returns>
		public override QueryResults Query(QueryParameter parameter)
		{
			StatisticDefinition statisticDefinition = this.GetStatisticDefinition();
			List<KeyValuePair<StatisticFilter, StatisticFilterLocation>> dataSource = this.ResolveAllStatisticFilters(statisticDefinition);

			var q = (from filter in dataSource
					orderby filter.Value, filter.Key.Ordinal
					select new
					{
						Id = FormatStatisticFilterKey(filter.Value, filter.Key.HeaderText),
						filter.Key.HeaderText,
						filter.Key.Ordinal,
						filter.Key.Description,
						filter.Key.PropertyLabel,
						Location = filter.Value
					}).AsQueryable();

			if (parameter.Expressions != null && parameter.Expressions.Count > 0)
			{
				QueryPredicate predicate = parameter.Expressions.Compile();
				q = q.Where(predicate.Predicate, predicate.Parameters);
			}

			if (parameter.SortExpression != null)
			{
				string sortExpression = parameter.SortExpression.Compile();
				q = q.OrderBy(sortExpression);
			}

			return new QueryResults(q.Count(), q);
		}

		/// <summary>
		/// Delete special statistic field by id from the statistic report which resolved by abstract method "GetStatisticDefinition" and save it by abstract method "SaveStatisticDefinition".
		/// </summary>
		/// <param name="entityId"></param>
		public override void Delete(string entityId)
		{
			StatisticDefinition statisticDefinition = this.GetStatisticDefinition();
			List<KeyValuePair<StatisticFilter, StatisticFilterLocation>> dataSource = this.ResolveAllStatisticFilters(statisticDefinition);
			if (dataSource.Count(kvp => FormatStatisticFilterKey(kvp.Value, kvp.Key.HeaderText) == entityId) > 0)
			{
				KeyValuePair<StatisticFilter, StatisticFilterLocation> statisticFilterToRemove = dataSource.FirstOrDefault(kvp => FormatStatisticFilterKey(kvp.Value, kvp.Key.HeaderText) == entityId);
				if (statisticFilterToRemove.Value == StatisticFilterLocation.Column)
				{
					List<StatisticFilter> allColumnFilters = statisticDefinition.Columns.ToList();
					allColumnFilters.Remove(statisticFilterToRemove.Key);
					statisticDefinition.Columns = allColumnFilters.ToArray();
				}
				else if (statisticFilterToRemove.Value == StatisticFilterLocation.Row)
				{
					List<StatisticFilter> allRowFilters = statisticDefinition.Rows.ToList();
					allRowFilters.Remove(statisticFilterToRemove.Key);
					statisticDefinition.Rows = allRowFilters.ToArray();
				}

				this.SaveStatisticDefinition(statisticDefinition);
			}
		}

		/// <summary>
		/// Set TempVariables for dynamic page configuration on "StatisticDefinition.Id" and "StatisticDefinition.Name".
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public override void SetupContextTempVariables(object sender, SetupApplicationContextVariablesEventArgs e)
		{
			StatisticDefinition statisticDefinition = this.GetStatisticDefinition();
			e.TempVariables["StatisticDefinition.Id"] = statisticDefinition.Id;
			e.TempVariables["StatisticDefinition.Name"] = statisticDefinition.Name;
		}

		/// <summary>
		/// Save statistic definition.
		/// </summary>
		/// <param name="statisticDefinition"></param>
		protected abstract void SaveStatisticDefinition(StatisticDefinition statisticDefinition);

		/// <summary>
		/// Get statistic definition for adding filter in or editing the filter.
		/// </summary>
		/// <returns></returns>
		protected abstract StatisticDefinition GetStatisticDefinition();

		private static string FormatStatisticFilterKey(StatisticFilterLocation location, string headerText)
		{
			return StatisticFieldDetailPanel.GenerateStatisticFilterId(location, headerText);
		}

		private List<KeyValuePair<StatisticFilter, StatisticFilterLocation>> ResolveAllStatisticFilters(StatisticDefinition statisticDefinition)
		{
			List<KeyValuePair<StatisticFilter, StatisticFilterLocation>> dataSource = new List<KeyValuePair<StatisticFilter, StatisticFilterLocation>>();
			if (statisticDefinition.Columns != null)
				dataSource.AddRange(statisticDefinition.Columns.Select(filter => new KeyValuePair<StatisticFilter, StatisticFilterLocation>(filter, StatisticFilterLocation.Column)));
			if (statisticDefinition.Rows != null)
				dataSource.AddRange(statisticDefinition.Rows.Select(filter => new KeyValuePair<StatisticFilter, StatisticFilterLocation>(filter, StatisticFilterLocation.Row)));

			return dataSource;
		}
	}
}

